package com.yunhe.abnormal.repository.base.impl;

import com.google.common.collect.Lists;
import com.yunhe.abnormal.domain.base.AlarmType;
import com.yunhe.common.model.PageParam;
import com.yunhe.abnormal.repository.base.AlarmTypeSession;
import com.yunhe.common.util.Neo4jConditionUtil;
import com.yunhe.common.util.QueryUtil;
import com.yunhe.common.util.StringUtil;
import org.neo4j.ogm.session.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Repository;

import java.util.*;

/**
 * 异常类型Session实现类
 * @author liuronglei
 */
@Repository
public class AlarmTypeSessionImpl implements AlarmTypeSession {
    @Autowired
    private Session session;

    @Override
    public Page<AlarmType> findByKeywordAndDtime(String queryStr, List<Long> dtime, PageParam pageParam) {
        StringBuilder str = new StringBuilder("match(at:AlarmType)");
        List<String> condition = new ArrayList<>();
        Map<String, Object> params = new HashMap<>();
        if (!StringUtil.isEmpty(queryStr)) {
            condition.add("(at.title=~('.*'+{queryStr}+'.*') or at.desc=~('.*'+{queryStr}+'.*') or at.title=~('.*'+{queryStr}+'.*'))");
            params.put("queryStr", queryStr);
        }
        if (dtime !=null && !dtime.isEmpty()) {
            if (dtime.get(0) != null) {
                condition.add("at.rtime>={startRtime}");
                params.put("startRtime", dtime.get(0));
            }
            if (dtime.size() > 1 && dtime.get(1) != null) {
                condition.add("at.rtime<={endRtime}");
                params.put("endRtime", dtime.get(1));
            }
        }
        StringBuilder query = new StringBuilder(str);
        query.append(Neo4jConditionUtil.getConditionStr(condition)).append(" return at order by at.rtime desc");
        if (pageParam != null) {
            PageRequest pr = PageRequest.of(QueryUtil.getPage(pageParam), QueryUtil.getSize(pageParam));
            if (QueryUtil.needPaging(pageParam)) {
                query.append(" skip {offset} limit {pageSize}");
                params.put("offset", pr.getOffset());
                params.put("pageSize", pr.getPageSize());
            }
            List<AlarmType> results = Lists.newArrayList(session.query(AlarmType.class, query.toString(), params));
            StringBuilder count = new StringBuilder(str);
            count.append(Neo4jConditionUtil.getConditionStr(condition)).append(" return count(id(at)) as count");
            List<Long> countResult = Lists.newArrayList(session.query(Long.class, count.toString(), params));
            Optional<Long> first = countResult.stream().findFirst();
            return new PageImpl<>(results, pr, first.orElse(0L));
        } else {
            List<AlarmType> results = Lists.newArrayList(session.query(AlarmType.class, query.toString(), params));
            return new PageImpl<>(results, PageRequest.of(0, results.size()), results.size());
        }
    }

    @Override
    public List<Long> getBoundRule(List<Long> ids) {
        String query = "match(ar:AlarmRule)-[:ALARM_TYPE_OF]->(at:AlarmType) where id(at) in {ids} return id(at)";
        Map<String, Object> params = new HashMap<>();
        params.put("ids", ids);
        return Lists.newArrayList(session.query(Long.class, query, params));
    }
}
